#import "mol3DView.h"
@implementation mol3DView
- (IBAction)toggleFullScreen:(id)sender
{
    if( FullScreenOn == true ) // we need to go back to non-full screen
    {
        [FullScreenWindow close];
        [StartingWindow setContentView: self];
        [StartingWindow makeKeyAndOrderFront: self];
        [StartingWindow makeFirstResponder: self];
        FullScreenOn = false;
    }
    else // FullScreenOn == false
    {
        unsigned int windowStyle;
        NSRect       contentRect;
		
        StartingWindow = [NSApp keyWindow];
        windowStyle    = NSBorderlessWindowMask; 
        contentRect    = [[NSScreen mainScreen] frame];
        FullScreenWindow = [[NSWindow alloc] initWithContentRect:contentRect
													   styleMask: windowStyle backing:NSBackingStoreBuffered defer: NO];
        if(FullScreenWindow != nil)
        {
            NSLog(@"Window was created");			
            [FullScreenWindow setTitle: @"myWindow"];			
            [FullScreenWindow setReleasedWhenClosed: YES];
            [FullScreenWindow setContentView: self];
            [FullScreenWindow makeKeyAndOrderFront:self ];
            [FullScreenWindow setLevel: NSScreenSaverWindowLevel - 1];
            [FullScreenWindow makeFirstResponder:self];
            FullScreenOn = true;
        }
    }
}

- (IBAction)toggleFrames:(id)sender {
	if([sender state]) f=0;else f=0.5;
}

- (void)initGL
{    
	// First, we must create an NSOpenGLPixelFormatAttribute
    NSOpenGLPixelFormat *nsglFormat;
    NSOpenGLPixelFormatAttribute attr[] = 
	{
        NSOpenGLPFADoubleBuffer,
		NSOpenGLPFAAccelerated,
		NSOpenGLPFAColorSize, BITS_PER_PIXEL,
		NSOpenGLPFADepthSize, DEPTH_SIZE,
        0 
	};
	
    [self setPostsFrameChangedNotifications: YES];
    nsglFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
    if(nsglFormat) { 
		NSLog(@"Invalid format... terminating.");
		[self setPixelFormat:nsglFormat]; 
	}
	[[self openGLContext] makeCurrentContext];
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
	glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
	glEnable(GL_COLOR_MATERIAL);
	glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
	GLfloat LightPosition[]= { 5.0f, 5.0f, 5.0f, 1.0f };
	GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f };
	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
	glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);
	glEnable(GL_LIGHT1);
	glEnable(GL_LIGHTING);
    first = YES;
    radius = 3;
    NSLog(@"end initGL");
}


// awake from nib is called when the window opens
- (void)awakeFromNib
{
	angX = M_PI/4;
	angY = M_PI/4;
	ang2Y = 0;
	ang2X = M_PI/2;
	[self initGL];
    NSLog(@"awakeFromNib");
    time = [ [NSTimer scheduledTimerWithTimeInterval: DEFAULT_TIME_INTERVAL
											  target:self
											selector:@selector(drawFrame)	//go to this method whenever the time comes
											userInfo:nil
											 repeats:YES]
			retain
			];
    // Add our timers to the EventTracking loop
    [[NSRunLoop currentRunLoop] addTimer: time forMode: NSEventTrackingRunLoopMode];
    // Add our timers to the ModelPanel loop
    [[NSRunLoop currentRunLoop] addTimer: time forMode: NSModalPanelRunLoopMode];
    NSLog(@"end awakeFromNib");
}


// this method is called whenever the window/control is reshaped
// it is also called when the control is first opened
- (void) reshape
{
    float aspect;
    NSSize bound = [self frame].size;
    aspect = bound.width / bound.height;
    // change the size of the viewport to the new width and height
    // this controls the affine transformation of x and y from normalized device 
    // coordinates to window coordinates (from the OpenGl 1.1 reference book, 2nd ed)
    glViewport(0, 0, bound.width, bound.height);
    glMatrixMode(GL_PROJECTION);
    // you must reload the identity before this or you'll lose your picture
    glLoadIdentity();
    gluPerspective(45.0f, (GLfloat)aspect, 0.1f,100.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

- (void)drawFrame
{
    // make this control the First Responder if this is the first time to draw the frame
    // there is probably some notification that would work more efficiently than this silly test
    // but I don't know what it is
    if( first )
    {
        first = NO; 
        if ([[NSApp keyWindow] makeFirstResponder:self] ) 
            NSLog( @"self apparently made first responder" );
        else 
            NSLog( @"self is not first responder"); 
    }
	
    // Clear the buffers!
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // this is where you would want to draw
	xCord = radius * cos(angY) * cos(angX);
	yCord =  radius* sin(angY);
	zCord = radius * sin(angX) * cos(angY);
	xCam = radius * cos(ang2Y) * cos(ang2X);
	yCam =  radius* sin(ang2Y);
	zCam = radius * sin(ang2X) * cos(ang2Y) - radius;
	gluLookAt(xCord,yCord,zCord, xCam, yCam, zCam, 0, 1, 0);
	int i=0;
	if (test !=NULL) while ((test+i)->m[0]!='E') {
		glTranslatef((test+i)->x, (test+i)->y, (test+i)->z);
		glColor3fv(molcolor(&(test+i)->m[0]));
		GLUquadric *q  = gluNewQuadric();
		gluSphere(q, f*calcbndr(&(test+i)->m[0]), 50, 50);
		glTranslatef(-((test+i)->x), -((test+i)->y), -((test+i)->z));
		if ((test+i)->parrent!=NULL) {
			glBegin(GL_LINES);
			if (f==0) glColor3fv(molcolor(&(test+i)->m[0]));else glColor3f(0.5, 0.5, 0.5);
			glVertex3f((test+i)->x, (test+i)->y, (test+i)->z);
			glVertex3f((test+i)->parrent->x, (test+i)->parrent->y, (test+i)->parrent->z);
			glEnd();
		}
		++i;
	}
    // flush the buffer! (send drawing to the screen)
    [[self openGLContext] flushBuffer];
	
}
- (IBAction)toggleCheck:(id)sender {
	f = 0.5 * [sender state];
	if (f==0) f=1;
}
/* This is the preferred way to determine events */
// if you want to get events sent to you, you must make yourself a first responder
- (BOOL)acceptsFirstResponder
{
    return YES;
}
- (BOOL)becomeFirstResponder
{
    return YES;
}

- (IBAction) newMol:(id)sender {
	char *c =[[ds tableView:sender objectValueForTableColumn:[[NSTableColumn alloc] initWithIdentifier:@"full"]  row:[sender selectedRow]] cString];
	ml = prasemolfile(c);
	test = calc3d(ml);
}
	
// handle key down events
// if you don't handle this, the system beeps when you press a key (how annoying)
- (void)keyDown:(NSEvent *)theEvent
{
    NSLog( @"key down" );
}
- (void) mouseDragged:(NSEvent *) theEvent {
	if ([theEvent modifierFlags] & NSControlKeyMask)
    {
        [self rightMouseDragged:theEvent];
    }else if ([theEvent modifierFlags] & NSShiftKeyMask) {
		ang2X+=[theEvent deltaX]/100;
		ang2Y+=[theEvent deltaY]/100;
	} else {
	angX+=[theEvent deltaX]/100;
	angY+=[theEvent deltaY]/100;
	}
}
- (void) rightMouseDragged:(NSEvent *) theEvent {
	radius+=[theEvent deltaX]/20;
}
// handle mouse up events (left mouse button)
- (void)mouseUp:(NSEvent *)theEvent
{
    NSLog( @"Mouse L up");    
}
// handle mouse up events (right mouse button)
- (void)rightMouseUp:(NSEvent *)theEvent
{
    NSLog( @"Mouse R up");
}
// handle mouse up events (other mouse button)
- (void)otherMouseUp:(NSEvent *)theEvent
{
    NSLog( @"Mouse O up");
}
- (void)savePanelDidEnd:(NSOpenPanel *)savePanel returnCode:(int)returnCode contextInfo:(void *)x
{
	NSString *path, *fullpath;

	
	if(returnCode == NSOKButton) {
		fullpath = [savePanel filename];
		unsigned char* planes[1];
		NSSize size;
		NSBitmapImageRep* representation;
		NSImage* image;
		
		size = [self bounds].size;
		NSMutableData * buffer = [NSMutableData dataWithLength:size.width*size.height*3];
		glReadBuffer(GL_BACK);
		glReadPixels(0, 0, size.width, size.height, GL_RGB, GL_UNSIGNED_BYTE,
					 [buffer mutableBytes]);
		planes[0] = [buffer mutableBytes];
		representation = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:planes
																 pixelsWide:size.width pixelsHigh:size.height bitsPerSample:8
															samplesPerPixel:3 hasAlpha:NO isPlanar:NO
															 colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:(size.width * 3)
															   bitsPerPixel:24];
		
		image = [[NSImage alloc] initWithSize:size];
		[image setFlipped:YES];
		[image lockFocus];
		[representation drawInRect:NSMakeRect(0,0,size.width,size.height)];
		[image unlockFocus];
		NSData *tiffData = [representation TIFFRepresentation];
		[tiffData writeToFile:fullpath atomically:YES];
	}
}

-(IBAction)save:(id)sender
{
	NSSavePanel *panel = [NSSavePanel savePanel];
	[panel beginSheetForDirectory:nil
							 file:@"untitled.tiff" 
				   modalForWindow:[self window]
					modalDelegate:self 
				   didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) 
					  contextInfo:NULL];
	
}
@end
